package ace.cmp.spring.data.jdbc.autoconfig;

import ace.cmp.spring.data.jdbc.core.properties.SpringDataJdbcProperties;
import ace.cmp.spring.data.jdbc.core.provider.ForceJdbcDialectProvider;
import java.util.Optional;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jdbc.repository.config.DialectResolver;
import org.springframework.data.jdbc.repository.config.EnableJdbcAuditing;
import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.data.relational.core.mapping.DefaultNamingStrategy;
import org.springframework.data.relational.core.mapping.NamingStrategy;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;

/**
 * @author caspar
 * @date 2023/4/3 15:59
 */
@EnableJdbcAuditing
@EnableConfigurationProperties({SpringDataJdbcProperties.class})
@AutoConfigureBefore({JdbcRepositoriesAutoConfiguration.class})
@Configuration
public class SpringDataJdbcAutoConfig {
  @ConditionalOnMissingBean
  @Bean
  public NamingStrategy namingStrategy() {
    return DefaultNamingStrategy.INSTANCE;
  }

  @Bean
  @ConditionalOnMissingBean
  public Dialect jdbcDialect(
      NamedParameterJdbcOperations operations, ForceJdbcDialectProvider forceJdbcDialectProvider) {

    Optional<Dialect> dialectOptional =
        forceJdbcDialectProvider.getDialect(operations.getJdbcOperations());

    if (dialectOptional.isPresent()) {
      return dialectOptional.get();
    }

    return DialectResolver.getDialect(operations.getJdbcOperations());
  }

  @Bean
  @ConditionalOnMissingBean
  public ForceJdbcDialectProvider forceJdbcDialectProvider(SpringDataJdbcProperties properties) {
    return new ForceJdbcDialectProvider(properties);
  }

  //    @Bean
  //    @ConditionalOnMissingBean
  //    public DateTimeProvider dateTimeProvider() {
  //        return () -> Optional.of(Instant.now());
  //    }
}
